<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>递归优化</title>
</head>

<body>

</body>

<script>
    function factorial(n, total = 0) {
        if (n == 0) return total;
        let result = factorial(n - 1, total + n)
        console.log(`result=${result}`); // 每次输出的都是最终结果

        return result;
    }
    // console.log(factorial(5));
    // console.log(factorial(100000)); //内存泄漏

    //使用蹦床函数优化递归
    function trampoline(fn) {
        return function (...args) {
            let result = fn(...args);
            //将递归改为循环
            while (typeof result === 'function') {
                result = result();
            }
            return result;
        }
    }
    function factorial2(n, total = 0) {
        if (n == 0) return total;
        return () => factorial2(n - 1, total + n);
    }
    const f = trampoline(factorial2);
    // console.log(f(100000));
    // console.log(f(5));
    //尾递归优化
    function ickt(fn) {
        let result;
        let isProcessing = false;
        let arguemntEque = [];
        return function inner(...cuArgs) {
            arguemntEque.push(cuArgs);
            if (!isProcessing) {
                isProcessing = true;
                while (arguemntEque.length > 0) {
                    result = fn.apply(this, arguemntEque.shift());
                    console.log(`result=${result}`); // 每次都是undefined，最后一次才是最终结果
                }
                isProcessing = false;
                return result;
            }
        }
    }
    const add = ickt((n, total = 0) => {
        if (n === 0) {
            return total;
        }
        return add(n - 1, total + n);
    })
    // console.log(add(3));
</script>

</html>